package org.iteam.bank.signed.service;

import org.apache.commons.lang3.StringUtils;
import org.iteam.bank.core.ReturnCode;
import org.iteam.bank.mina.client.IoSessionConn;
import org.iteam.bank.mina.client.IoSessionFactory;
import org.iteam.bank.mina.client.ResultMessage;
import org.iteam.bank.mina.utils.ConfigLoader;
import org.iteam.commons.codec.AESCoder;
import org.iteam.commons.codec.HMACCoder;
import org.iteam.commons.utils.PkGenerator;
import org.iteam.mina.Constant;
import org.iteam.mina.message.BaseMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class SMSService {
	private static final Logger logger = LoggerFactory.getLogger(SignedService.class);
	private IoSessionFactory factory = IoSessionFactory.getInstance();
	private String toket = PkGenerator.genUUIDD();
	private final int rule = 0x00000000;
	private final int ver = 0x00000001;
	private static final String ip = ConfigLoader.get("sms.ip");
	private static final Integer port = ConfigLoader.getInteger("sms.port", 10088);
	private static final String KEY_AES = ConfigLoader.get("sms.KEY_AES");
	private static final String KEY_HMAC = ConfigLoader.get("sms.KEY_HMAC");
	public static final String id = "id";
	public static final String returnCode = "returnCode";
	public static final String returnCodeMsg = "returnCodeMsg";
	public static final String seq = "seq";
	/** 1：注册短信 */
	public static final Integer TYPE_REGISTER = 1;
	/** 2：找回登录密码短信 */
	public static final Integer TYPE_RETRIEVE_LOGIN_PASSWORD = 2;
	/** 3：找回支付密码短信 */
	public static final Integer TYPE_RETRIEVE_PAY_PASSWORD = 3;
	/** 4支付密码短信 */
	public static final Integer TYPE_PAY_PASSWORD = 4;

	private SMSService() {
		super();
	}

	public static SMSService getInstance() {
		return Subclass.service;
	}

	private static final class Subclass {
		public static final SMSService service = new SMSService();
	}

	/**
	 * 发送短信
	 * 
	 * @param tel
	 *            电话
	 * @param type
	 *            类型 1：注册短信，2：找回登录密码短信，3：找回支付密码短信，4支付密码短信
	 * @return 成功内容：{
	 *         "id":"88F50196B96B42E2AD9D074E1415BA77","returnCode":0,"returnCodeMsg"
	 *         :"成功","seq":"I33"} <br/>
	 * <br/>
	 *         失败内容：{"returnCode":1,"returnCodeMsg":"短信模版[3]不存在"} <br/>
	 * <br/>
	 *         returnCode非0表示失败
	 */
	// "id":"88F50196B96B42E2AD9D074E1415BA77","returnCode":0,"returnCodeMsg":"成功","seq":"I33"
	public JSONObject sendSms(String tel, Integer type) {
		BaseMessage req = new BaseMessage();
		// req.setLength(length);
		req.setCmd(0x11030300);
		req.setRule(rule);
		req.setVer(ver);
		req.setSeq(PkGenerator.genUUIDD());
		req.setToken(toket);
		JSONObject contentJson = new JSONObject();
		contentJson.put("tel", tel);
		contentJson.put("type", type);
		IoSessionConn sessionConn = null;
		try {
			logger.debug(" 发送验证码：{}", contentJson.toJSONString());
			byte[] contentByte = contentJson.toJSONString().getBytes(Constant.UTF_8);
			req.setContent(AESCoder.encrypt(contentByte, KEY_AES));
			req.setVerify(HMACCoder.encryptHMAC(req.getContent(), KEY_HMAC));
			sessionConn = factory.getSession(ip, port);
			sessionConn.write(req, true);
			ResultMessage res = new ResultMessage(sessionConn.read(true));
			if (res.isSuccess() && res.verify(KEY_HMAC)) {
				res.decrypt(KEY_AES);
				JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
				logger.debug(" 发送验证码结果：{}", jsonObject.toJSONString());
				return jsonObject;

			} else {
				res.decrypt(KEY_AES);
				JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
				logger.debug(" 发送验证码结果：{}", jsonObject.toJSONString());
				return jsonObject;
			}
		} catch (Exception e) {
			JSONObject jsonObject = new JSONObject();
			jsonObject.put(returnCode, ReturnCode.SYSTEM_ERRPR.getCode());
			jsonObject.put(returnCodeMsg, ReturnCode.SYSTEM_ERRPR.getMsg());
			logger.error(e.getMessage(), e);
			logger.debug(" 发送验证码结果：{}", jsonObject.toJSONString());
			return jsonObject;
		} finally {
			factory.releaseSession(sessionConn);
		}
	}

	/**
	 * 验证短信
	 * 
	 * @param tel
	 *            电话
	 * @param type
	 *            类型 1：注册短信，2：找回登录密码短信，3：找回支付密码短信，4支付密码短信
	 * @param id
	 *            验证码发送ID
	 * @param captcha
	 *            验证码
	 * @return 成功内容：{"returnCode":0,"returnCodeMsg":"成功"} <br/>
	 * <br/>
	 *         失败内容：{"returnCode":1,"returnCodeMsg":"验证码输入错误"} <br/>
	 * <br/>
	 *         returnCode非0表示失败
	 */
	public JSONObject validateSms(String tel, Integer type, String id, String captcha) {
		BaseMessage req = new BaseMessage();
		// req.setLength(length);
		req.setCmd(0x11030400);
		req.setRule(rule);
		req.setVer(ver);
		req.setSeq(PkGenerator.genUUIDD());
		req.setToken(toket);
		JSONObject contentJson = new JSONObject();
		contentJson.put("tel", tel);
		contentJson.put("type", type);
		contentJson.put("id", id);
		contentJson.put("captcha", captcha);
		IoSessionConn sessionConn = null;
		try {
			logger.debug(" 发送验证码进行验证：{}", contentJson.toJSONString());

			byte[] contentByte = contentJson.toJSONString().getBytes(Constant.UTF_8);
			req.setContent(AESCoder.encrypt(contentByte, KEY_AES));
			req.setVerify(HMACCoder.encryptHMAC(req.getContent(), KEY_HMAC));
			sessionConn = factory.getSession(ip, port);
			sessionConn.write(req, true);
			ResultMessage res = new ResultMessage(sessionConn.read(true));
			if (res.isSuccess() && res.verify(KEY_HMAC)) {
				res.decrypt(KEY_AES);
				JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
				logger.debug(" 发送验证码进行验证结果：{}", jsonObject.toJSONString());
				return jsonObject;

			} else {
				res.decrypt(KEY_AES);
				JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
				logger.debug(" 发送验证码进行验证结果：{}", jsonObject.toJSONString());
				return jsonObject;
			}
		} catch (Exception e) {
			JSONObject jsonObject = new JSONObject();
			jsonObject.put(returnCode, ReturnCode.SYSTEM_ERRPR.getCode());
			jsonObject.put(returnCodeMsg, ReturnCode.SYSTEM_ERRPR.getMsg());
			logger.error(e.getMessage(), e);
			logger.debug(" 发送验证码进行验证结果：{}", jsonObject.toJSONString());
			return jsonObject;
		} finally {
			factory.releaseSession(sessionConn);
		}
	}

	public static boolean isSuccess(JSONObject jsonObject) {
		if (jsonObject != null && jsonObject.containsKey(returnCode)
				&& StringUtils.equals(jsonObject.getString(returnCode), String.valueOf(ReturnCode.SUCCESS.getCode()))) {
			return true;
		}
		return false;
	}

	public static String getErrorMsg(JSONObject jsonObject) {
		if (jsonObject != null && jsonObject.containsKey(returnCodeMsg)) {
			return jsonObject.getString(returnCodeMsg);
		}
		return null;
	}

	public static String getID(JSONObject jsonObject) {
		if (jsonObject != null && jsonObject.containsKey(id)) {
			return jsonObject.getString(id);
		}
		return null;
	}
}
